#include "koroCard.h"
#include "myTask.h"

uint8_t koro_analyze_data(struct koroCardStu *koro, struct koroCardDataStu *cardData){
    uint8_t dataBuf[5] = {
        [0] = 0x25,
        [1] = cardData->id,
        [2] = cardData->meshData,
        [3] = 0x68,
    };
    // 发送给受控设备
    jdy25m_mesh_send(koro->jdy, cardData->meshAddrU.meshADDR_16, dataBuf, 4, JDY25M_MESH_CMD_NOACK);

    // 播放音频
    ch_play_folder(koro->ch, cardData->audioFolder, cardData->audioIndex);

    // 播放灯效
    koroAnime.anime = KORO_A_BLINK;
    koroAnime.ForT = 2;
    koroAnime.seconds = 1;
    koroAnime.rgb888.red = 50;
    koroAnime.rgb888.green = 0;
    koroAnime.rgb888.blue = 0;

    koro_anime_play(&koroAnime);

    return 0;
}

/* 卡片存储数据格式，第二扇区第零块
0:      0x25
1:      库洛牌 ID
2:      0x68
3:      0x25
4~5:    受控设备 mesh 地址，2 Byte，大端
6:      发送给受控设备的数据，1 Byte
7:      指定音频文件夹，1 Byte
8:      指定音频序号，1 Byte
9:      0x68
*/
int koro_read_card(struct koroCardStu *koro, struct koroCardDataStu *cardData){
    uint8_t i;
    uint8_t errNum;
    uint8_t cKey[6] = {
        [0] = 0xFF,
        [1] = 0xFF,
        [2] = 0xFF,
        [3] = 0xFF,
        [4] = 0xFF,
        [5] = 0xFF,
    };
    uint8_t dataBuf[20];
    uint8_t cardID[4];

    for(i = 0; i < 4; i ++){
        cardID[i] = 0;
    }
    errNum = rc522_card_read_block(koro->rc, CARD_AUTHENT1A, 0x08, cKey, dataBuf, cardID); // 第二扇区第一块
    

    if(errNum == RC522_ERR_OK){
        if((dataBuf[0] == 0x25) && (dataBuf[2] == 0x68) && (dataBuf[3] == 0x25) && (dataBuf[9] == 0x68)){
            cardData->id = dataBuf[1];
            cardData->meshAddrU.meshADDR_8.meshADDR_H = dataBuf[4];
            cardData->meshAddrU.meshADDR_8.meshADDR_L = dataBuf[5];
            cardData->meshData = dataBuf[6];
            cardData->audioFolder = dataBuf[7];
            cardData->audioIndex = dataBuf[8];
        }else {
            return KORO_NOTKORO;
        }
    }else if(errNum == RC522_ERR_NOCARD){
        return KORO_NOCARD;
    }else {
        return KORO_ERR;
    }

    return KORO_OK;
}

int koro_write_card(struct koroCardStu *koro, struct koroCardDataStu *cardData){
    uint8_t i;
    uint8_t errNum;
    uint8_t dataBuf[20] = {
        [0] = 0x25,
        [1] = cardData->id,
        [2] = 0x68,
        [3] = 0x25,
        [4] = cardData->meshAddrU.meshADDR_8.meshADDR_H,
        [5] = cardData->meshAddrU.meshADDR_8.meshADDR_L,
        [6] = cardData->meshData,
        [7] = cardData->audioFolder,
        [8] = cardData->audioIndex,
        [9] = 0x68,
    };
    uint8_t cKey[6] = {
        [0] = 0xFF,
        [1] = 0xFF,
        [2] = 0xFF,
        [3] = 0xFF,
        [4] = 0xFF,
        [5] = 0xFF,
    };
    uint8_t cardID[4];

    for(i = 0; i < 4; i ++){
        cardID[i] = 0;
    }
    errNum = rc522_card_write_block(koro->rc, CARD_AUTHENT1A, 0x08, cKey, dataBuf, cardID); // 第二扇区第一块

    if(errNum == RC522_ERR_OK){
        return KORO_OK;
    }else if(errNum == RC522_ERR_NOCARD){
        return KORO_NOCARD;
    }else {
        return KORO_ERR;
    }
}


/**
 * @brief 灯效：闪烁
 * 
 * @param ws 
 * @param freq 频率：1~255 Hz, 0 为停止闪烁
 * @param rgb888 
 * @return uint16_t 与下一次刷新的间隔 ms
 */
uint16_t koro_anime_blink(struct ws2812Stu *ws, uint8_t freq, struct ws2812PixelDescribeStu *rgb888){
    static uint8_t i = 0;
    if(freq == 0){
        return 0;
    }

    if(i){
        i = 0;
        ws2812_set_all_color(ws, rgb888->red, rgb888->green, rgb888->blue);
    }else {
        i ++;
        ws2812_set_all_color(ws, 0, 0, 0);
    }
    ws2812_refresh(ws);

    return 500/freq;
}


/**
 * @brief 灯效：呼吸灯，50 级亮度变化
 * 
 * @param ws 
 * @param period 周期，0 为停止
 * @param rgb888 
 * @return uint16_t 与下一次刷新的间隔 ms
 */
uint16_t koro_anime_breathe(struct ws2812Stu *ws, uint8_t period, struct ws2812PixelDescribeStu *rgb888){
    static uint8_t i = 0;
    static uint16_t j = 0;
    if(period == 0){
        return 0;
    }

    j = (j++)%50;

    if(j == 0){
        i = !i;
    }
    
    if(i){
        ws2812_set_all_color(ws, rgb888->red - (uint8_t)(rgb888->red/50.0*j), rgb888->green - (uint8_t)(rgb888->green/50.0*j), rgb888->blue - (uint8_t)(rgb888->blue/50.0*j));
    }else {
        ws2812_set_all_color(ws, (uint8_t)(rgb888->red/50.0*j), (uint8_t)(rgb888->green/50.0*j), (uint8_t)(rgb888->blue/50.0*j));
    }

    ws2812_refresh(ws);

    return period * 10;
}

void koro_anime_play(struct koroAnimeStu *anime){
    // 设置动画播放标志位偏移
    wsAnimeFlag = anime->anime + KORO_A_OFFSET;
    if(anime->seconds){ // 如果设置了动画播放时长（seconds > 0），那么通知 ws2812 守护进程来控制播放时间
        wsAnimeTime = anime->seconds; // 设置播放总时长
        wsAnimeTimeFlag = 1; // 守护进程标志位
    }
}
